/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dal/allocator.h"
#include "dal/qos_policy.h"

static const dal_duration_t duration_zero = {0, 0};
static const dal_duration_t duration_100ms = {0, 100000000};
static const dal_duration_t duration_infinite = {DAL_INFINITE_SECONDS, DAL_INFINITE_NANOSECONDS};

dal_domain_participant_qos_t* dal_create_default_participant_qos()
{
    dal_domain_participant_qos_t* qos = dal_domain_participant_qos_allocate();
    INIT_SEQUENCE(octet, &qos->user_data.value);
    qos->entity_factory.autoenable_created_entities = DAL_TRUE;
    qos->localhost_only = DAL_FALSE;
    INIT_SEQUENCE_WITH_CAPACITY(dal_locator_t, &qos->multicast_locator_seq, 5);
    INIT_SEQUENCE_WITH_CAPACITY(dal_locator_t, &qos->unicast_locator_seq, 5);

    return qos;
}

void dal_delete_participant_qos(dal_domain_participant_qos_t* qos)
{
    if (NULL == qos)
        return;
    DEEP_CLEAR_SEQUENCE(octet, &qos->user_data.value);
    DEEP_CLEAR_SEQUENCE(dal_locator_t, &qos->multicast_locator_seq);
    DEEP_CLEAR_SEQUENCE(dal_locator_t, &qos->unicast_locator_seq);
    dal_domain_participant_qos_free(qos);
}

dal_topic_qos_t* dal_create_default_topic_qos()
{
    dal_topic_qos_t* qos = dal_topic_qos_allocate();
    INIT_SEQUENCE(octet, &(qos->topic_data.value));
    qos->durability.kind = DAL_VOLATILE_DURABILITY_QOS;

    qos->durability_service.service_cleanup_delay = duration_zero;
    qos->durability_service.history_kind = DAL_KEEP_LAST_HISTORY_QOS;
    qos->durability_service.history_depth = 1;
    qos->durability_service.max_samples = DAL_LENGTH_UNLIMITED;
    qos->durability_service.max_instances = DAL_LENGTH_UNLIMITED;
    qos->durability_service.max_samples_per_instance = DAL_LENGTH_UNLIMITED;

    qos->deadline.period = duration_infinite;
    qos->latency_budget.duration = duration_zero;

    qos->liveliness.kind = DAL_AUTOMATIC_LIVELINESS_QOS;
    qos->liveliness.lease_duration = duration_infinite;

    qos->reliability.kind = DAL_BEST_EFFORT_RELIABILITY_QOS;
    qos->reliability.max_blocking_time = duration_100ms;
    qos->destination_order.kind = DAL_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;

    qos->history.kind = DAL_KEEP_LAST_HISTORY_QOS;
    qos->history.depth = 1;

    qos->resource_limits.max_samples = 5000;
    qos->resource_limits.max_instances = 10;
    qos->resource_limits.max_samples_per_instance = 400;

    qos->transport_priority.value = 0;
    qos->lifespan.duration = duration_infinite;
    qos->ownership.kind = DAL_SHARED_OWNERSHIP_QOS;

    return qos;
}

void dal_delete_topic_qos(dal_topic_qos_t* qos)
{
    if (NULL == qos)
        return;
    CLEAR_SEQUENCE(octet, &(qos->topic_data.value));
    dal_topic_qos_free(qos);
}

dal_publisher_qos_t* dal_create_default_publisher_qos()
{
    dal_publisher_qos_t* qos = dal_publisher_qos_allocate();
    qos->presentation.access_scope = DAL_INSTANCE_PRESENTATION_QOS;
    qos->presentation.coherent_access = DAL_FALSE;
    qos->presentation.ordered_access = DAL_FALSE;

    qos->partition.name.n = 0;
    qos->partition.name.strs = NULL;
    INIT_SEQUENCE(octet, &(qos->group_data.value));

    qos->entity_factory.autoenable_created_entities = DAL_TRUE;

    return qos;
}

void dal_delete_publisher_qos(dal_publisher_qos_t* qos)
{
    if (NULL == qos)
        return;

    CLEAR_SEQUENCE(octet, &(qos->group_data.value));
    dal_publisher_qos_free(qos);
}

dal_subscriber_qos_t* dal_create_default_subscriber_qos()
{
    dal_subscriber_qos_t* qos = dal_subscriber_qos_allocate();
    qos->presentation.access_scope = DAL_INSTANCE_PRESENTATION_QOS;
    qos->presentation.coherent_access = DAL_FALSE;
    qos->presentation.ordered_access = DAL_FALSE;

    qos->partition.name.n = 0;
    qos->partition.name.strs = NULL;
    INIT_SEQUENCE(octet, &(qos->group_data.value));

    qos->entity_factory.autoenable_created_entities = DAL_TRUE;

    return qos;
}

void dal_delete_subscriber_qos(dal_subscriber_qos_t* qos)
{
    if (NULL == qos)
        return;

    CLEAR_SEQUENCE(octet, &(qos->group_data.value));
    dal_subscriber_qos_free(qos);
}

dal_datawriter_qos_t* dal_create_default_datawriter_qos()
{
    dal_datawriter_qos_t* qos = dal_datawriter_qos_allocate();
    qos->durability.kind = DAL_TRANSIENT_LOCAL_DURABILITY_QOS;

    qos->durability_service.service_cleanup_delay = duration_zero;
    qos->durability_service.history_kind = DAL_KEEP_LAST_HISTORY_QOS;
    qos->durability_service.history_depth = 1;
    qos->durability_service.max_samples = DAL_LENGTH_UNLIMITED;
    qos->durability_service.max_instances = DAL_LENGTH_UNLIMITED;
    qos->durability_service.max_samples_per_instance = DAL_LENGTH_UNLIMITED;

    qos->deadline.period = duration_infinite;
    qos->latency_budget.duration = duration_zero;

    qos->liveliness.kind = DAL_AUTOMATIC_LIVELINESS_QOS;
    qos->liveliness.lease_duration = duration_infinite;

    qos->reliability.kind = DAL_RELIABLE_RELIABILITY_QOS;
    qos->reliability.max_blocking_time = duration_100ms;

    qos->destination_order.kind = DAL_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;

    qos->history.kind = DAL_KEEP_LAST_HISTORY_QOS;
    qos->history.depth = 1;

    qos->resource_limits.max_samples = 10000;
    qos->resource_limits.max_instances = 10;
    qos->resource_limits.max_samples_per_instance = 1000;

    qos->transport_priority.value = 0;

    qos->lifespan.duration = duration_infinite;

    INIT_SEQUENCE(octet, &(qos->user_data.value));

    qos->ownership.kind = DAL_SHARED_OWNERSHIP_QOS;

    qos->ownership_strength.value = 0;

    qos->writer_data_lifecycle.autodispose_unregistered_instances = DAL_TRUE;

    return qos;
}

void dal_delete_datawriter_qos(dal_datawriter_qos_t* qos)
{
    if (NULL == qos)
        return;
    CLEAR_SEQUENCE(octet, &(qos->user_data.value));
    dal_datawriter_qos_free(qos);
}

dal_datareader_qos_t* dal_create_default_datareader_qos()
{
    dal_datareader_qos_t* qos = dal_datareader_qos_allocate();
    qos->durability.kind = DAL_VOLATILE_DURABILITY_QOS;
    qos->deadline.period = duration_infinite;
    qos->latency_budget.duration = duration_zero;

    qos->liveliness.kind = DAL_AUTOMATIC_LIVELINESS_QOS;
    qos->liveliness.lease_duration = duration_infinite;

    qos->reliability.kind = DAL_BEST_EFFORT_RELIABILITY_QOS;
    qos->reliability.max_blocking_time = duration_100ms;

    qos->destination_order.kind = DAL_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;

    qos->history.kind = DAL_KEEP_LAST_HISTORY_QOS;
    qos->history.depth = 1;

    qos->resource_limits.max_samples = 10000;
    qos->resource_limits.max_instances = 10;
    qos->resource_limits.max_samples_per_instance = 1000;

    INIT_SEQUENCE(octet, &(qos->user_data.value));

    qos->ownership.kind = DAL_SHARED_OWNERSHIP_QOS;

    qos->time_based_filter.minimum_separation = duration_zero;

    qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = duration_infinite;
    qos->reader_data_lifecycle.autopurge_disposed_samples_delay = duration_infinite;
    return qos;
}

void dal_delete_datareader_qos(dal_datareader_qos_t* qos)
{
    if (NULL == qos)
        return;
    CLEAR_SEQUENCE(octet, &(qos->user_data.value));
    dal_datareader_qos_free(qos);
}
